package web.eshop.order;

import application.MySession;
import domain.shop.BasketItem;
import domain.shop.Product;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import service.facade.customer.ShopCustomerService;
import web.eshop.panels.ShopBasePanel;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Display base order page, where customer can change order yet.
 */
public final class OrderPanel1 extends ShopBasePanel {

    @SpringBean
    private ShopCustomerService customerService;
    @SpringBean
    private MySession mySession;
    private LoadableDetachableModel<List<BasketItem>> orderProductsModel;
    private Form mainForm = new Form("mainForm");

    public OrderPanel1(String id, final OrderPage parent) {
        super(id);
        add(mainForm);
        WebMarkupContainer container = new WebMarkupContainer("empty");
        add(container);
        if (mySession.getBasket().size() != 0) {

            container.setVisible(false);
            orderProductsModel = new LoadableDetachableModel<List<BasketItem>>() {

                @Override
                protected List<BasketItem> load() {
                    Map<Long, Integer> basket = mySession.getBasket();
                    List<BasketItem> basketItems = new ArrayList<BasketItem>();
                    for (Long productId : basket.keySet()) {
                        Product product = customerService.findProductById(productId);
                        BasketItem basketItem = new BasketItem();
                        basketItem.setMultiplicity(basket.get(productId));
                        basketItem.setProduct(product);
                        basketItem.setPrice(product.getPrice());
                        basketItems.add(basketItem);
                    }
                    return basketItems;
                }
            };

            add(new BasketItemListView("order", orderProductsModel));
            mainForm.add(new Label("totalPrice", new AbstractReadOnlyModel<String>() {

                @Override
                public String getObject() {
                    return mySession.getTotalPriceAsString();
                }
            }));
            mainForm.add(new Button("acceptOrder") {

                @Override
                public void onSubmit() {
                    OrderPanel2 acceptOrderPanel = new OrderPanel2("content",
                            parent);
                    parent.replacePanel(acceptOrderPanel);
                }
            });

        } else {
            mainForm.setVisible(false);
            add(new EmptyPanel("order").setVisible(false));
        }
    }

    private class BasketItemListView extends ListView<BasketItem> {

        public BasketItemListView(String id, IModel<? extends List<? extends BasketItem>> model) {
            super(id, model);
        }

        @Override
        protected void populateItem(final ListItem<BasketItem> item) {
            item.add(new Form<BasketItem>("form", new CompoundPropertyModel<BasketItem>(item.getModel())) {

                {
                    add(new Label("name"));
                    add(new Label("price"));
                    add(new Label("sumPrice", new LoadableDetachableModel<BigDecimal>() {

                        @Override
                        protected BigDecimal load() {
                            return (item.getModelObject().getPrice().multiply(
                                    BigDecimal.valueOf(item.getModelObject().getMultiplicity())));
                        }
                    }));


                    add(new TextField<Integer>("multiplicity").setRequired(true));
                    add(new Button("update") {

                        @Override
                        public void onSubmit() {
                            if (item.getModelObject().getMultiplicity() <= 0) {
                                error(getLocalizer().getString("order.multiplicity", this));
                                item.getModelObject().setMultiplicity(1);
                            } else {
                                customerService.updateBasketItem(item.getModelObject());
                            }
                        }
                    });
                    add(new Button("delete") {

                        @Override
                        public void onSubmit() {
                            customerService.removeProductFromBasket(item.getModelObject().getProduct());

                            if (mySession.getBasket().size() == 0) {
                                setResponsePage(OrderPage.class);
                            } else {
                                BasketItemListView.this.detachModels();
                            }

                        }
                    });
                }
            });
        }
    }
}
